#pragma once
#include <atomic>
#include <cstdint>
#include <map>
#include <memory>
#include <mutex>
#include <string.h>
#include "Util.h"
#include "XnccType.h"
namespace xncc {
namespace sys {
    class EventFd;
}
namespace msg {
    // struct MsgHeaderInThread
    // {
    //     uint32_t               len;
    //     types::message_id_t    id;
    //     types::connection_id_t connId;
    //     types::thread_id_t     tid;
    // };
    class FIFOQueueTestElementTest;
    class FIFOQueueTest
    {
      public:
        using s_ptr = std::shared_ptr<FIFOQueueTest>;
        FIFOQueueTest(types::queue_size_t size, bool autoExpand = false);
        ~FIFOQueueTest() = default;

        char* getWriteBuffer(types::queue_size_t len);
        char* tryGetWriteBuffer(types::queue_size_t len);
        void  finishWrite();
        char* getReadBuffer(types::queue_size_t len);
        void  finishRead();
        void  setNeedNotify();

        [[nodiscard]] std::string dump() const;

        [[nodiscard]] types::queue_id_t id() const { return queueId_; }

        std::shared_ptr<xncc::sys::EventFd> notifyId() const { return notifyfd_; }

      private:
        void updateCurrentReadPtr();
        void updateCurrentWritePtr();

      private:
        bool                                                     autoExpand_;
        std::map<int, std::shared_ptr<FIFOQueueTestElementTest>> bufferList_;
        std::shared_ptr<xncc::sys::EventFd>                      notifyfd_ = nullptr;
        std::shared_ptr<FIFOQueueTestElementTest>                currReadPtr_;
        std::shared_ptr<FIFOQueueTestElementTest>                currWritePtr_;
        std::mutex                                               mutex_;
        int                                                      lastReadIndex_;
        bool                                                     isNeedNotify_;
        const types::queue_id_t                                  queueId_;
    };
}  // namespace msg
}  // namespace xncc
